﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Warensoft.Socket.Extension;
namespace Warensoft.Socket.MessageDataStructs
{
    public abstract   class PackageBase:MemoryStream,IPackage 
    {
        #region Extension methods
        public  int ReadInt()
        {
            return StreamExtension.ReadInt(this);      
        }
        public void WriteInt(int value)
        {
            StreamExtension.WriteInt(this,value );
        }
        public  short ReadShort()
        {
            return StreamExtension.ReadShort(this);
        }
        public  void WriteShort(short value)
        {
            StreamExtension.WriteShort(this,value);
        }

        public  string ReadUTF()
        {
            return StreamExtension.ReadUTF(this);
        }
        public  string ReadUTFBytes(int length)
        {
            return StreamExtension.ReadUTFBytes(this,length);
        }
        public  void WriteUTF(string s)
        {
            StreamExtension.WriteUTF(this,s);
        }
        public  void WriteUTFBytes(string s)
        {
            StreamExtension.WriteUTFBytes(this,s);
        }
        /// <summary>
        /// 将流指针重置为0
        /// </summary>
        /// <param name="strm"></param>
        public void ResetStreamPointer()
        {
            this.Position = 0;
        }
      
        #endregion
        
        protected MemoryStream contentStream;
        
        #region IPackage Members
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="buffer">包括消息名称，长度以及消息正文的字节序列</param>
        /// <param name="index">开始位置</param>
        /// <param name="count">长度</param>
        public PackageBase(byte[] buffer, int index, int count)
            : base(buffer, index, count)
        {   
            Init();
        }
        
        private void Init()
        {
            this.name = this.ReadUTF();
            this.messageLength = this.ReadShort();
            this.contentStream = new MemoryStream();
            var buffer = new byte[this.messageLength];
            this.Read(buffer, 0, this.messageLength);
            this.contentStream.Write(buffer ,0,this.messageLength );
            this.contentStream.Position = 0;
        }
        
        public PackageBase()
        {
            this.contentStream = new MemoryStream();
            this.messageLength = 0;
        }
        private string name;
        public string Name
        {
            get
            {
                return this.name;
            }
            set
            {
                this.name = value;
            }
        }
        private short messageLength;
        public   short MessageLength
        {
            get
            {
                return this.messageLength;
            }
            set
            {
                this.messageLength = value;
            }
        }

        public Application  Application
        {
            get;
            set;
        }

        public Message Concat(PackageBase  anotherPackage)
        {
            Message m = new Message();
            m.Packages.Add(this);
            m.Packages.Add(anotherPackage );
            return m;
        }
     
        #endregion

        #region IDisposable Members
       
        public new  void Dispose()
        {
            this.contentStream.Close();
            base.Dispose();
            
        }

        #endregion




        #region IPackage Members

        public byte[] ContentBuffer
        {
            get
            {
                return this.contentStream.ToArray();
            }
            
        }
        /// <summary>
        /// 将该消息转化为字节序列
        /// </summary>
        /// <returns>表示消息的字节序列</returns>
        public override byte[] ToArray()
        {
            this.FillContentStream();
            this.WriteUTF(this.name);
            this.WriteShort((short )this.contentStream .Length );
            var contentBytes = this.contentStream.ToArray();
            this.Write(contentBytes, 0, contentBytes.Length);
            return base.ToArray();
        }
        
        
        protected abstract void FillContentStream();
        #endregion



        #region IPackage Members

        byte[] IPackage.ContentBuffer
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        

        #endregion
    }
}
